package com.xyzwps.mvckotlin.handler

import com.xyzwps.mvckotlin.handler.helper.andNest
import com.xyzwps.mvckotlin.handler.helper.auth
import com.xyzwps.mvckotlin.handler.helper.nest
import com.xyzwps.mvckotlin.handler.helper.routes
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
import org.springframework.web.reactive.function.server.*

import org.springframework.web.reactive.function.server.RequestPredicates.GET
import org.springframework.web.reactive.function.server.RequestPredicates.POST
import org.springframework.web.reactive.function.server.RouterFunctions.route

/**
 * 这里有两种可以使用的路由:
 *
 * 1. 普通路由，见下面的 `articleRouters`
 * 2. DSL 路由，见下面的 `commonRouters`
 *
 * DSL 路由描述能力有限，要是想给路由加 filter 之类的东西，DSL 是不足以支撑的。
 */
@Configuration
class RouterConfig(val demoHandler: DemoHandler,
                   val errorHandler: ErrorHandler,
                   val commonHandler: CommonHandler,
                   val articleHandler: ArticleHandler,
                   val entryHandler: EntryHandler,
                   val userHandler: UserHandler) {

    fun articleRouters() = route(GET("/id/{id}"), HandlerFunction { articleHandler.get()(it) })
            .and(routes(GET("/new"), articleHandler.newArticlePage()).auth())
            .and(routes(GET("/change/{id}"), articleHandler.changeArticlePage()).auth())
            .and(routes(POST("/save"), articleHandler.save()).auth())


    fun userRouters() = routes(GET("/register"), entryHandler.registerPage())
            .and(routes(POST("/register"), entryHandler.register()))
            .and(routes(GET("/login"), entryHandler.loginPage()))
            .and(routes(POST("/login"), entryHandler.login()))
            .and(routes(GET("/logout"), entryHandler.logoutPage()).auth())
            .and(routes(POST("/logout"), entryHandler.logout()).auth())
            .and(routes(GET("/space"), userHandler.space()).auth())

    @Bean
    fun routers() = nest("/user", userRouters())
            .andNest("/article", articleRouters())


    @Bean
    fun commonRouters() = router {
        GET("/", commonHandler.index())
        GET("/home", commonHandler.home())
        GET("/404", errorHandler::x404)
    }

    @Bean
    fun demoRouters() = router {
        "/demo".nest {
            GET("/render-error", demoHandler.renderError())
            GET("/session", demoHandler.session())
            POST("/body", demoHandler.body())
            GET("/path/{whatever}", demoHandler.get())
            POST("/", demoHandler.post())
        }
    }

}
